"""
翻牌猜对

开始桌面摆放着4行6列的卡片。

其中图案可能是1~9，A,B,C共计12种，每种2张。
初始时，将所有牌打乱顺序。


鼠标点击翻牌。并记录翻牌次数。
翻牌时：
1. 如果翻牌次数是0，则记录并展开当前牌，并使翻牌次数+1；
2. 再次翻的牌，不能是已经翻开的牌；
3. 如果翻牌次数是1，则翻开当前牌，并对进行验证：
3.1. 如果当前牌面与已翻牌面不同，则两种牌展示{wait_seconds}秒后均再翻回去，并重置翻牌次数；
3.2. 如果当前牌面与已翻牌面相同，则两种牌展示{wait_seconds}秒后均消除，并重置翻牌次数；
3.3. 等待比较期间，所有事件无效。
4. 如果所有牌均通过此种方式消除，则宣告胜利。


绘画内容：
1. 24张牌（使用精灵处理），每张牌有3种状态：展示正面，展示背面，不展示。
2. 提示文本。包括倒计时或者胜利/失败状态。


事件：
通过鼠标左键翻牌。

核心数据：
1. 牌面矩阵；（隐藏）
2. 展示矩阵；（展示）

"""

import arcade
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random

WINDOW_WIDTH=370
WINDOW_HEIGHT=370
WINDOW_TITLE='double card'

# 卡片参数
CARD_WIDTH=50
CARD_HEIGHT=80
CARD_BORDER_WIDTH = 3
CARD_FONT_SIZE=24

CARD_COL_COUNT=6
CARD_ROW_COUNT=4
CARD_MARGIN=10

def get_gray_texture():
    # 创建一个纯色矩形纹理
    # PIL.Image.new(mode, size, color)​ 是用于创建一个 ​新的空白图像
    image = Image.new('RGBA', (CARD_WIDTH, CARD_HEIGHT), arcade.color.GRAY)
    return arcade.Texture(image)

def create_char_image(char):
    """
    创建带有红色边框、中间包含指定字符的白色背景图片
    参考方法：https://liaoxuefeng.com/books/python/third-party-modules/pillow/index.html
    
    参数:
    char (str): 要显示在图片中央的字符
    """
    # 创建新图片（50x80 像素，RGB 模式，白色背景）
    img = Image.new('RGBA', (CARD_WIDTH, CARD_HEIGHT), (255, 255, 255))
    draw = ImageDraw.Draw(img)
    
    # 获取字体（尝试使用系统字体，若未指定则使用默认字体）
    # 所有系统默认字体均未找到，使用 Pillow 默认字体
    font = ImageFont.load_default(CARD_FONT_SIZE)
    
    # 绘制深红色边框 (RGB: 139,0,0)
    
    draw.rectangle(
        [(CARD_BORDER_WIDTH, CARD_BORDER_WIDTH), (CARD_WIDTH - CARD_BORDER_WIDTH, CARD_HEIGHT - CARD_BORDER_WIDTH)],
        outline=(139, 0, 0), 
        width=CARD_BORDER_WIDTH
    )
    
    # 绘制文字（黑色）
    char_position=(CARD_WIDTH/2-CARD_FONT_SIZE/3,CARD_HEIGHT/2-CARD_FONT_SIZE/2)
    draw.text(char_position, char, fill=(0, 0, 0), font=font,align='center')

    return img  # 返回图片对象，可选择不保存直接使用

def calc_card_position(cr):
    c,r=cr
    x=(CARD_WIDTH+CARD_MARGIN)*c+CARD_WIDTH/2+CARD_MARGIN
    y=(CARD_HEIGHT+CARD_MARGIN)*r+CARD_HEIGHT/2+CARD_MARGIN
    return (x,y)

# 卡片背面初始化
CARD_BACK_TEXTURE=get_gray_texture()
# 卡片正面初始化
CARD_FRONT_TEXTURES=[]
CHAR_LIST=['1','2','3','4','5','6','7','8','9','A','B','C']
for c in CHAR_LIST:
    CARD_FRONT_TEXTURES.append(arcade.Texture(create_char_image(c)))

class Card(arcade.Sprite):

    def __init__(self,card_type):
        # 卡牌精灵，由牌面和内容构成。牌面包括正面和反面，分别使用白色和灰色表示，内容使用文本纹理表示。
        super().__init__(CARD_BACK_TEXTURE)
        self.textures.append(CARD_FRONT_TEXTURES[card_type])
        self.card_type=card_type
        # card face表示正反面。1正面0反面
        self.card_face=0
        self.r=None
        self.c=None


    def update(self, delta_time: float = 1/60):
        self.texture=self.textures[self.card_face]
        pass



class GameView(arcade.View):

    def __init__(self):
        super().__init__()
        self.player_sprite_list=None

        self.sprite_matrix=[[None]*CARD_COL_COUNT for _ in range(CARD_ROW_COUNT)]

        self.background_color=arcade.color.AMAZON
        self.cur_card_pos=None

    def setup(self):
        self.player_sprite_list=arcade.SpriteList()

        idxs=list(range(len(CARD_FRONT_TEXTURES)*2))
        random.shuffle(idxs)

        for i in idxs:
            card_type=i%len(CARD_FRONT_TEXTURES)
            player_sprite=Card(card_type)

            r=i//CARD_COL_COUNT
            c=i%CARD_COL_COUNT
            x,y=calc_card_position((c,r))

            player_sprite.center_x=x
            player_sprite.center_y=y

            player_sprite.r=r
            player_sprite.c=c

            self.sprite_matrix[r][c]=player_sprite
            
        
            self.player_sprite_list.append(player_sprite)

    def on_draw(self):
        self.clear()
        self.player_sprite_list.draw()

    def on_update(self, delta_time):
        self.player_sprite_list.update()


    def on_mouse_press(self, x, y, button, modifiers):
        if button==arcade.MOUSE_BUTTON_LEFT:
            # 快速根据坐标获取被点击的精灵（只可能有一个）
            clicked_sprites=arcade.get_sprites_at_point((x,y),self.player_sprite_list)
            clicked_sprites[0].card_face=1-clicked_sprites[0].card_face
            if self.cur_card_pos:
                if clicked_sprites[0].card_type==self.cur_card_pos.card_type:
                    print('消失')
                    clicked_sprites[0].visible=False
                    self.cur_card_pos.visible=False
                else:
                    
                    self.cur_card_pos=None
            else:
                self.cur_card_pos=clicked_sprites[0]
        pass


def main():
    """ Main function """
    # Create a window class. This is what actually shows up on screen
    window = arcade.Window(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_TITLE)

    # Create and setup the GameView
    game = GameView()
    game.setup()

    # Show GameView on screen
    window.show_view(game)

    # Start the arcade game loop
    arcade.run()


if __name__ == "__main__":
    main()
        